﻿using Microsoft.Win32;
using System;
using System.ComponentModel;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;

namespace WpfWebScanner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Uri _uri;
        private SaveFileDialog _saveFileDialog = new SaveFileDialog();
        private BackgroundWorker worker = new BackgroundWorker();

        public MainWindow()
        {
            InitializeComponent();

            txtUrl.SelectionStart = txtUrl.Text.Length;
            txtUrl.SelectionLength = 0;

            this.WindowState = System.Windows.WindowState.Maximized;

            _saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            _saveFileDialog.RestoreDirectory = true;
            _saveFileDialog.Filter = "Text file (*.txt)|*.txt|All files (*.*)|*.*";

            worker.WorkerReportsProgress = true;
            worker.DoWork += worker_DoWork;
            worker.ProgressChanged += worker_ProgressChanged;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            TimeSpan ts = (TimeSpan)e.Result;
            txtUrl.AppendText(", Time elapsed: " + ts.Seconds.ToString() + " sec");
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            txtUrl.Clear();
            txtUrl.AppendText(e.ProgressPercentage + "%");
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            DateTime t = DateTime.Now;
            Tuple<string, string> args = e.Argument as Tuple<string, string>;

            for (int i = 0; i < 10000; i++)
            {
                worker.ReportProgress((i + 1) * 100 / 10000);
                File.WriteAllText(args.Item1 + i.ToString(), args.Item2);
            }

            e.Result = DateTime.Now - t;
        }

        private async void btnScan_Click(object sender, RoutedEventArgs e)
        {
            var url = txtUrl.Text;

            if (url.Trim() == String.Empty)
            {
                MatchWords(txtHtml.Text);
                return;
            }



            if (!Uri.TryCreate(url, UriKind.Absolute, out _uri))
            {
                MessageBox.Show("Please check url.",
                    "Invalid URL",
                    MessageBoxButton.OK, MessageBoxImage.Exclamation);
                return;
            }

            HttpClient client = new HttpClient();

            try
            {
                btnScan.IsEnabled = false;
                txtHtml.Text = "Please wait while requesting " + _uri.AbsoluteUri;
                txtResult.Clear();

                var html = await client.GetStringAsync(_uri);
                txtHtml.Text = html;

                MatchWords(html);
            }
            catch (HttpRequestException exception)
            {
                MessageBox.Show(exception.Message + "\nPlease Check Your Internet Connection.",
                    "Http Request Exception.",
                    MessageBoxButton.OK, MessageBoxImage.Exclamation);

                txtHtml.Clear();
            }
            finally
            {
                btnScan.IsEnabled = true;
            }


        }

        private void MatchWords(string source)
        {
            var matches = Regex.Matches(source, @"\p{IsArmenian}+");

            foreach (var item in matches)
            {
                txtResult.AppendText(Regex.Replace(item.ToString(), @"[^\w]", String.Empty));
                txtResult.AppendText(Environment.NewLine);
            }
        }

        private async void MenuItemSaveAs_Click(object sender, RoutedEventArgs e)
        {
            _saveFileDialog.FileName = _uri != null ? _uri.Host : String.Empty;

            if (_saveFileDialog.ShowDialog() == true)
            {
                if (worker.IsBusy != true)
                {
                    worker.RunWorkerAsync(Tuple.Create(_saveFileDialog.FileName, txtResult.Text));
                }
            }

        }

        // Using Async for File Access (C# and Visual Basic) 
        // https://msdn.microsoft.com/en-us/library/jj155757.aspx
        private async Task WriteTextAsync(string filePath, string text)
        {
            byte[] encodedText = Encoding.Unicode.GetBytes(text);

            using (FileStream sourceStream = new FileStream(filePath,
                FileMode.Append, FileAccess.Write, FileShare.None,
                bufferSize: 4096, useAsync: true))
            {
                await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
            };
        }
    }
}
